package cn.xorange.commons.datasource.configuration;

import cn.xorange.commons.datasource.constants.DataDefaultConstants;
import cn.xorange.commons.datasource.constants.DataSourceContextHolder;
import cn.xorange.commons.datasource.service.DataSourceService;
import cn.xorange.commons.datasource.service.DynamicDataSource;
import cn.xorange.commons.exception.DataException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Configuration
@AutoConfigureBefore({org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration.class,
        com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class})
public class DSConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public Map<String,Object> defaultDsProperties(){
        Map<String,Object> map = new HashMap<>();
        map.put("druid", DataDefaultConstants.druidConfig());
        map.put("sys", DataDefaultConstants.sysDB());
        log.debug("Initializing [defaultDsProperties]");
        return map;
    }

    @Bean
    @DependsOn({"defaultDsProperties"})
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public Map<String,Object> defaultDruidProperties(){
        Map<String,Object> map = DataDefaultConstants.druidConfig();
        log.debug("Initializing [defaultDruidProperties]");
        return map;
    }


    DataSourceService dataSourceService;

    @Primary
    @Bean()
    @DependsOn({"defaultDruidProperties"})
    @ConditionalOnMissingBean
    public DataSource dynamicDataSource(){
        dataSourceService = new DataSourceService();
        /** String transaction = StringUtils.toString(this.defaultDsProperties().get("transaction")); */
        dataSourceService.setDataSource(this.defaultDsProperties());
        DynamicDataSource dynamicDataSource = new DynamicDataSource();

        //配置数据源集合
        dynamicDataSource.setDataSources(dataSourceService.getDataSources());
        //配置默认数据源
        dynamicDataSource.setDefaultDataSource(dataSourceService.getDataSources().get(dataSourceService.getPrimary()));

        log.debug("Initializing [dynamicDataSource]");
        return dynamicDataSource;
    }
    @Bean
    @DependsOn({"dynamicDataSource"})
    public Map<String,String> dataSourceKeys(){
        log.debug("Initializing [dataSourceKeys]");
        return this.dataSourceService.getDataSourceKeys();
    }
    @Bean
    @DependsOn({"dynamicDataSource"})
    public String primaryKey(){
        log.debug("Initializing [primaryKey]");
        return this.dataSourceService.getPrimary();
    }


    /**
     * 判断数据源在系统中是否存在
     */
    public boolean isExistDs(String dataSourceKey) {
        if( Objects.isNull(this.dataSourceKeys().get(dataSourceKey))){
            throw DataException.dataSourceNotFound(dataSourceKey);
        }else {
            return true;
        }
    }

    /** 获取数据源类型 */
    public String getDsType(){
        String dsKey = DataSourceContextHolder.getDataSourceKey();
        if (Objects.isNull(dsKey)){
            dsKey = this.primaryKey();
        }
        return this.dataSourceKeys().get(dsKey);
    }

}
